home *** CD-ROM | disk | FTP | other *** search
/ PC World 2008 September / PCWorld_2008-09_cd.bin / v cisle / sadanastroju / greasemonkey-0.8.20080609.0-fx.xpi / chrome / greasemonkey.jar / chromeFiles / content / menucommander.js < prev    next >
Text File  |  2008-06-09  |  5KB  |  175 lines

  1. function GM_MenuCommander() {
  2.   GM_log("> GM_MenuCommander")
  3.  
  4.   this.menu = document.getElementById("userscript-commands-sb");
  5.   this.keyset = document.getElementById("mainKeyset");
  6.   this.menuPopup = this.menu.firstChild;
  7.  
  8.   this.menuItems = [];
  9.   this.keys = [];
  10.   this.attached = false;
  11.  
  12.   this.menu2 = document.getElementById("userscript-commands-sb2");
  13.   this.menuPopup2 = this.menu2.firstChild;
  14.   this.menuItems2 = [];
  15.  
  16.   GM_log("< GM_MenuCommander")
  17. }
  18.  
  19. GM_MenuCommander.prototype.registerMenuCommand =
  20.   function(commandName, commandFunc, accelKey, accelModifiers, accessKey) {
  21.     GM_log("> GM_MenuCommander.registerMenuCommand");
  22.  
  23.     // Protection against item duplication
  24.     for (var i = 0; i < this.menuItems.length; i++) {
  25.       if (this.menuItems[i].getAttribute("label") == commandName) {
  26.         return;
  27.       }
  28.     }
  29.  
  30.     GM_log("accelKey: " + accelKey);
  31.     GM_log("modifiers: " + accelModifiers);
  32.     GM_log("accessKey: " + accessKey);
  33.  
  34.     var menuItem = this.createMenuItem(commandName, commandFunc, accessKey);
  35.     var menuItem2 = this.createMenuItem(commandName, commandFunc, accessKey);
  36.     this.menuItems.push(menuItem);
  37.     this.menuItems2.push(menuItem2);
  38.  
  39.     if (accelKey) {
  40.       var key = this.createKey(commandFunc, accelKey, accelModifiers, menuItem);
  41.       this.keys.push(key);
  42.     }
  43.  
  44.     // if this menucommander is for the current document, we should add the
  45.     // elements immediately. otherwise it will be added in attach()
  46.     if (this.attached) {
  47.       this.menuPopup.appendChild(menuItem);
  48.       this.menuPopup2.appendChild(menuItem2);
  49.  
  50.       if (accelKey) {
  51.         this.keyset.appendChild(key);
  52.       }
  53.  
  54.       this.setDisabled(false);
  55.     }
  56.  
  57.     GM_log("< GM_MenuCommmander.registerMenuCommand")
  58.   };
  59.  
  60. GM_MenuCommander.prototype.attach = function() {
  61.   GM_log("> GM_MenuCommander.attach");
  62.  
  63.   for (var i = 0; i < this.menuItems.length; i++) {
  64.     this.menuPopup.appendChild(this.menuItems[i]);
  65.     this.menuPopup2.appendChild(this.menuItems2[i]);
  66.   }
  67.  
  68.   for (var i = 0; i < this.keys.length; i++) {
  69.     this.keyset.appendChild(this.keys[i]);
  70.   }
  71.  
  72.   this.setDisabled(this.menuItems.length == 0);
  73.   this.attached = true;
  74.  
  75.   GM_log("< GM_MenuCommander.attach");
  76. };
  77.  
  78. GM_MenuCommander.prototype.detach = function() {
  79.   GM_log("> GM_MenuCommander.detach");
  80.   GM_log("* this.menuPopup: " + this.menuPopup);
  81.   GM_log("* this.menuPopup2: " + this.menuPopup2);
  82.  
  83.   for (var i = 0; i < this.menuItems.length; i++) {
  84.     this.menuPopup.removeChild(this.menuItems[i]);
  85.     this.menuPopup2.removeChild(this.menuItems2[i]);
  86.   }
  87.  
  88.   for (var i = 0; i < this.keys.length; i++) {
  89.     this.keyset.removeChild(this.keys[i]);
  90.   }
  91.  
  92.   this.setDisabled(true);
  93.   this.attached = false;
  94.  
  95.   GM_log("< GM_MenuCommander.detach");
  96. };
  97.  
  98. //TODO: restructure accel/access validation to be at register time.
  99. //Should throw when called, not when building menu.
  100. //This has side effect of one script's bad reg affecting another script's.
  101.  
  102.  
  103. GM_MenuCommander.prototype.createMenuItem =
  104. function(commandName, commandFunc, accessKey) {
  105.   GM_log("> GM_MenuCommander.createMenuItem");
  106.  
  107.   var menuItem = document.createElement("menuitem");
  108.   menuItem._commandFunc = commandFunc;
  109.   menuItem.setAttribute("label", commandName);
  110.   menuItem.setAttribute("oncommand", "this._commandFunc()");
  111.  
  112.   if (accessKey) {
  113.     if (typeof(accessKey) == "string" && accessKey.length == 1) {
  114.       menuItem.setAttribute("accesskey", accessKey);
  115.     } else {
  116.       throw "accessKey must be a single character";
  117.     }
  118.   }
  119.  
  120.   GM_log("< GM_MenuCommander.createMenuItem");
  121.   return menuItem;
  122. };
  123.  
  124. GM_MenuCommander.prototype.createKey =
  125.   function(commandFunc, accelKey, modifiers, menuItem) {
  126.     GM_log("> GM_MenuCommander.createKey");
  127.  
  128.     var key = document.createElement("key");
  129.  
  130.     if ((typeof accelKey) == "number") {
  131.       GM_log("keycode: " + accelKey);
  132.       key.setAttribute("keycode", accelKey);
  133.     } else if ((typeof accelKey) == "string" && accelKey.length == 1) {
  134.       GM_log("key: " + accelKey);
  135.       key.setAttribute("key", accelKey);
  136.     } else {
  137.       throw "accelKey must be a numerical keycode or a single character";
  138.     }
  139.  
  140.     GM_log("modifiers: " + modifiers);
  141.     key.setAttribute("modifiers", modifiers);
  142.  
  143.     // hack, because listen("oncommand", commandFunc) does not work!
  144.     // this is ok because .detach() gets called when the document is unloaded
  145.     // and this key is destroyed
  146.     key._commandFunc = commandFunc;
  147.     key.setAttribute("oncommand", "this._commandFunc()");
  148.  
  149.     var id = "userscript-command-" + this.keys.length;
  150.     key.setAttribute("id", id);
  151.     menuItem.setAttribute("key", id);
  152.  
  153.     GM_log("< GM_MenuCommander.createKey");
  154.     return key;
  155.   };
  156.  
  157. GM_MenuCommander.prototype.setDisabled = function(disabled) {
  158.   var menu = this.menu;
  159.   var marker = menu.nextSibling;
  160.   var parent = menu.parentNode;
  161.  
  162.   var menu2 = this.menu2;
  163.   var marker2 = menu2.nextSibling;
  164.   var parent2 = menu2.parentNode;
  165.  
  166.   menu.setAttribute("disabled", disabled);
  167.   menu2.setAttribute("disabled", disabled);
  168.  
  169.   parent.removeChild(menu);
  170.   parent.insertBefore(menu, marker);
  171.  
  172.   parent2.removeChild(menu2);
  173.   parent2.insertBefore(menu2, marker2);
  174. };
  175.